package com.kingsoft.dc.khaos.listener

import java.util.concurrent.CopyOnWriteArrayList

import scala.collection.JavaConverters._
import scala.reflect.ClassTag
import scala.util.control.NonFatal

/**
  * Created by chengguangqing on 2019/5/28.
  */
trait ListenerBus[L <: AnyRef, E] {

  private val listeners = new CopyOnWriteArrayList[L]()

  final def addListener(listener: L): Unit = {
    listeners.add(listener)
  }

  final def removeListener(listener: L): Unit = {
    listeners.remove(listener)
  }

  final def postToAll(event: E):Unit={
    val iter = listeners.iterator()
    while(iter.hasNext) {
      val listener = iter.next()
      try{
        doPostEvent(listener,event)
      } catch {
        case NonFatal(e) =>
          print(s"Listener ${this.getClass.getAnnotations} throw an exception",e)
      }
    }
  }

  private def findListenersByClass[T <: L: ClassTag]():Seq[T] ={
    val clazz = implicitly[ClassTag[T]].runtimeClass
    listeners.asScala.filter(_.getClass == clazz).map(_.asInstanceOf[T]).toSeq
  }

  protected def doPostEvent(listener:L, event:E): Unit
}
